/*
 * @Author: wwssaabb
 * @Date: 2021-07-26 16:52:49
 * @LastEditTime: 2021-08-13 14:55:35
 * @FilePath: \react-admin-server\router\api.js
 */
const router = require('koa-router')()
const path = require('path')

router.prefix('/api')

const {User}=require('../model/user')
const {check,run}=require('../hash')
router.post('/login',async (ctx,next)=>{
  const {username,password}=ctx.request.body
  let user=await User.findOne({username})
  let data={}
  if(user){
    let isPass=await check(password,user.password)
    if(isPass){
      data.code=200
      data.msg='登录成功'
      data.data=user
    }else{
      data.code=401
      data.msg='用户名或密码错误'
      data.data=null
    }
  }else{
    data.code=401
    data.msg='用户名或密码错误'
    data.data=null
  }
  ctx.status=200
  ctx.body=data
})

const fs=require('fs')
router.post('/upload',async (ctx,next)=>{
  const {file}=ctx.request.files
  file.path=file.path.replace('E:\\myProject\\demo\\react-admin-server\\public\\upload\\','http://localhost:3333/upload/')
  ctx.body={file,code:200,msg:'上传成功'}
})

/* 
  删除图片
  path，必填
*/
router.post('/upload/delete',async (ctx,next)=>{
  const body = ctx.request.body
  let data={}
  let doc=await Goods.findOne({_id:body.id})
  doc.imgs.splice(doc.imgs.findIndex(i=>i===body.path),1)
  doc.save()
  try {
    body.path=body.path.replace('http://localhost:3333/upload/',path.join(__dirname,'../public/upload/'))
    fs.rmSync(body.path)
    data.code=200
    data.msg='删除成功'
    data.res=res
  } catch (error) {
    data.code=200
    data.msg='文件不存在或已删除。'
    data.error=error.message
  }
  ctx.status=data.code
  ctx.body=data
})

//获取所有的类别
const {categories}=require('../model/categories')
router.get('/categories',async (ctx,next)=>{
  let res
  try {
    res=await categories.find()
  } catch (error) {
    res={message:error.message}
  }
  ctx.body=res
})

//修改类别名,
/* 
  id为大类的id，必填
  parent_index，如果要改写第三、二级则必填
  child_index，如果要改写第三级分类名则必填
  rename为需要重新设置的类名，必填
 */
router.post('/rename',async (ctx,next)=>{
  const {id,parent_index,child_index,rename}=ctx.request.body
  
  let category=await categories.findOne({_id:id})
  let _parent=category.children.map((i,index)=>{
    return i.children.length-1
  })
  if(id===undefined||rename===undefined||(child_index!==undefined&&parent_index===undefined)){
    ctx.status=400
    ctx.body={message:'参数不正确'}
    return
  }else{
    if(parseInt(parent_index)>_parent.length-1||parseInt(child_index)>_parent[parent_index]){
      ctx.status=400
      ctx.body={message:'参数超过有效值范围'}
      return
    }
  }
  
  let target=child_index!==undefined?`children.${parent_index}.children.${child_index}.name`:parent_index!==undefined?`children.${parent_index}.name`:'name'
  try {
    res=await categories.updateOne({_id:id},{[target]:rename})
    res.message='修改成功'
  } catch (error) {
    res={message:error.message}
  }
  ctx.body=res
})

/* 
  添加分类，只支持添加到一到三级
  id为大类的id，
  parent_index，
  name，为需要设置的类名，必填
*/
router.post('/addCategory',async (ctx,next)=>{
  const {id,parent_index,name}=ctx.request.body
  let res
  try {
    if(name===undefined||(parent_index!==undefined&&id===undefined)){
      ctx.status=400
      ctx.body={code:400,message:'参数错误'}
    }else{
      if(id===undefined&&parent_index===undefined){//创建一级类别
        res=await categories.create({name,children:[]})
        res.message='创建成功'
        ctx.status=200
      }else if(id!==undefined&&parent_index===undefined){//创建二级类别
        let category=await categories.findOne({_id:id})
        res=await categories.updateOne({_id:id},{$push:{'children':{name,children:[],id:id+'_c2_'+category.children.length}}})
        res.message='创建成功'
        ctx.status=200
      }else if(id!==undefined&&parent_index!==undefined){//创建三级类别
        let category=await categories.findOne({_id:id})
        let target=`children.${parent_index}.children`
        let info={
          level:3,
          parent:{name:category.children[parent_index].name,index:parent_index},
          grandpa:{id,name:category.name}
        }
        res=await categories.updateOne({_id:id},{$push:{[target]:{name,goods:[],id:id+'_c3_'+category.children[parent_index].children.length,info}}})
        res.message='创建成功'
        ctx.status=200
      }else{
        ctx.status=400
        res={code:400,message:'参数错误'}
      }
      ctx.body=res
  }
  } catch (error) {
    ctx.status=400
    ctx.body={code:400,message:error.message}
  }
})

/* 
  删除tu.my图床上传的图片
  md5，md5的值 
*/
const token='3bd7d715ed2d34e753e0128679ec4e1f'
router.post('/delete',async (ctx,next)=>{
  const {md5}=ctx.request.body
  let res=await axios.post('https://tu.my/api/images',{page:1,rows:50},{headers:{token}})
  let current_page=res.data.data.current_page
  let total_page=res.data.data.last_page
  if(current_page<total_page){
    id=await new Promise(async (resolve,reject)=>{
      for (let i = current_page+1; i <= total_page; i++) {
        res=await axios.post('https://tu.my/api/images',{page:i,rows:50},{headers:{token}})
        let target=res.data.data.data.find(i=>i.md5===md5)
        if(target){
          resolve(target.id)
        }
      }
    })
  }else{
    id=res.data.data.data.find(i=>i.md5===md5).id
  }
  let final_res
  if(id){
    final_res=await axios.post('https://tu.my/api/delete',{id},{headers:{token}})
  }
  ctx.body=final_res||final_res.data.status===200?{code:200,message:'删除成功'}:{code:200,message:'删除失败'}
})

/* 
  添加商品或者删除商品
  --添加商品
    name,商品名称，必填
    desc,商品描述，必填
    price,商品价格，必填
    category,商品，必填价格，必填
    imgs,商品图片，必填
    detail,商品详情富文本，必填
  -- 返回 新建的商品对象，包含商品id

  --删除商品
    id,商品id，必填
  -- 返回 成功消息对象，例如{code:200,msg:'删除成功'}
*/
const {Goods}=require('../model/goods')
router.post('/product/addOrDel',async (ctx,next)=>{
  const {id,name,desc,price,category,imgs,detail}=ctx.request.body
  if(id){
    let res=await Goods.deleteOne({_id:id})
    ctx.status=200
    ctx.body={code:200,msg:'删除成功'}
  }else{
    if(!name||!desc||!price||(!category||JSON.stringify(category)==='{}')||imgs.length===0||!detail){
      ctx.status=400
      ctx.body={code:400,msg:'参数错误，添加商品失败'}
    }else{
      let data={}
      try {
        data.data=await Goods.create({name,desc,price,category,imgs,detail})
        data.code=200
        data.msg='创建成功'
      } catch (error) {
        data.code=400
        data.msg='创建失败'
      }
      ctx.status=data.code
      ctx.body=data
    }
  }
  
})

/* 
  修改商品
  id,必填
  name,desc,price,category,imgs,detail ,选填
*/
router.post('/product/modify',async (ctx,next)=>{
  const {id,name,desc,price,category,imgs,detail}=ctx.request.body
  if(!id){
    ctx.status=400
    ctx.body={code:400,msg:'参数错误，id缺失'}
  }else{
    let data={}
    try {
      let doc=await Goods.findOne({_id:id})
      doc.name=name?name:doc.name
      doc.desc=desc?desc:doc.desc
      doc.price=price?price:doc.price
      doc.category=category?JSON.parse(category):doc.category
      doc.imgs=imgs?JSON.parse(imgs):doc.imgs
      doc.detail=detail?detail:doc.detail
      doc.save()
      data.data=doc
      data.code=200
      data.msg='修改成功'
    } catch (error) {
      data.code=400
      data.msg='修改失败'
      data.error=error.message
    }
    ctx.status=data.code
    ctx.body=data
  }
})

/* 
  获取商品列表
*/
router.get('/product/list',async (ctx,next)=>{
  let res=await Goods.find()
  ctx.status=200
  ctx.body={code:200,msg:'获取成功',data:res}
})

/* 
  改变商品状态
  _id
*/
router.post('/product/updateStatus',async (ctx,next)=>{
  const {_id} = ctx.request.body
  let data={}
  try {
    let doc=await Goods.findOne({_id})
    doc.status=doc.status===1?0:1
    doc.save()
    data.code=200
    data.msg='修改成功'
    data.data=doc
  } catch (error) {
    data.code=400
    data.msg='修改失败'
  }
  ctx.status=data.code
  ctx.body=data
})

/* 
  获取用户列表
*/
router.get('/users',async (ctx,next)=>{
  let res=await User.find({}).populate('roles','name')
  ctx.status=200
  ctx.body=res
})

/* 
  --创建用户
    username，必填项,length4-12
    password，必填项,length6
    email，必填项,
    phone，必填项,length11
    role_id，必填项
    name，选填
  --返回创建成功的对象
*/
const Joi=require('joi')
const UserSchema=Joi.object({
  username:Joi.string().required().min(2).max(12).error(new Error('用户名不符合验证规则，需4-12个有效字符组成')),
  password:Joi.string().required().min(6).error(new Error('密码不符合验证规则，需至少6个有效字符组成')),
  email:Joi.string().required().email().error(new Error('邮箱地址不符合验证规则')),
  phone:Joi.string().required().min(11).max(11).error(new Error('手机号码不符合验证规则')),
  role_id:Joi.string().required().error(new Error('角色不符合验证规则'))
})

router.post('/user/create',async (ctx,next)=>{
  const {username,password,email,phone,role_id}=ctx.request.body
  // const msgs=['用户名有4-12个有效字符组成，且','密码最少由6个字符组成']
  /* 
    服务器验证 ...暂时先简单验证
  */

  if([username,password,email,phone,role_id].some(i=>i===undefined)){
    ctx.status=400
    ctx.body={code:400,msg:'参数错误'}
    return
  }
  let data={}
  try {
    const _password=await run(password)
    let params=await UserSchema.validateAsync({username,password:_password,email,phone,role_id})
    data.data=await User.create(params)
    data.code=200
    data.msg='创建成功'
  } catch (error) {
    data.code=400
    data.msg='创建失败'
    data.error=error.message
  }
  ctx.status=data.code
  ctx.body=data
})

/* 
  修改客户
  id，必填
*/
router.post('/user/modify',async (ctx,next)=>{
  const {id,username,email,phone,role_id}=ctx.request.body
  if(!id){
    ctx.status=400
    ctx.body={code:400,msg:'参数错误'}
    return
  }
  
  let data={}
  try {
    data.data=await User.updateOne({_id:id},{$set:{username,email,phone,role_id}})
    data.code=200
    data.msg='修改成功'
  } catch (error) {
    data.code=400
    data.msg='创建失败'
    data.error=error.message
  }
  ctx.status=data.code
  ctx.body=data
})

/* 
  删除用户
    id，必填
  返回消息对象
*/
router.post('/user/delete',async (ctx,next)=>{
  const {id} = ctx.request.body
  if(!id){
    ctx.status=400
    ctx.body={code:400,msg:'参数错误'}
  }
  let res={}
  try {
    res.data=await User.findOneAndDelete({_id:id})
    res.code=200
    res.msg='删除成功'
  } catch (error) {
    res={code:400,msg:error.message}
  }
  ctx.status=res.code
  ctx.body=res
})

/* 
  获取角色列表
*/
const {Role}=require('../model/role')
router.get('/roles',async (ctx,next)=>{
  let res=await Role.find({})
  ctx.status=200
  ctx.body=res
})

/* 
  添加角色
  name
*/
router.post('/role/add',async (ctx,next)=>{
  const {name}=ctx.request.body
  if(!name){
    ctx.code=400
    ctx.body={code:400,msg:'参数错误，缺少name'}
    return 
  }
  let data={}
  try {
    data.data=await Role.create({name})
    data.code=200
    data.msg='创建成功'
  } catch (error) {
    data.code=400
    data.msg='创建失败'
    data.error=error.message
  }
  ctx.code=data.code
  ctx.body=data
})

/* 
  修改角色权限
  id，必填
  menus，Array
  auth_name,auth_time ,选填，填写时是授权
*/
router.post('/role/modify',async (ctx,next)=>{
  const {id,menus,auth_name,auth_time} = ctx.request.body
  let data={}
  if(!id){
    ctx.status=400
    ctx.body={code:400,msg:'参数错误，未提供ID'}
    return
  }
  try {
    let doc=await Role.findOne({_id:id})
    doc.menus=menus
    if(auth_name&&auth_time){
      if(!doc.auth_name){
        doc.auth_name=auth_name
        doc.auth_time=auth_time
      }
    }else{
      throw Error('参数错误')
    }
    doc.save()
    data.data=doc
    data.code=200
    data.msg='设置成功'
    data.isSelfRole=doc._id===id
  } catch (error) {
    data.code=400
    data.msg='设置失败'
    data.error=error.message
  }
  ctx.status=data.code
  ctx.body=data
})

module.exports=router
